package com.sto.stoapp.server;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

import com.sto.stoapp.StoApplication;
import com.sto.stoapp.activity.R;
import com.sto.stoapp.db.StoFilePreference;
import com.sto.stoapp.db.manager.ServerSmsManager;
import com.sto.stoapp.download.EnunDownLoad;
import com.sto.stoapp.file.OrderNoticeTempFile;
import com.sto.stoapp.http.MessageType;
import com.sto.stoapp.http.request.ServerSmsRequest;
import com.sto.stoapp.http.response.TimeSynchResponse;
import com.sto.stoapp.log.ExceptionLog;
import com.sto.stoapp.thread.BasicDataDLThread;
import com.sto.stoapp.thread.CodeIssueThread;
import com.sto.stoapp.thread.DeleteDataThread;
import com.sto.stoapp.thread.OrderDownThread;
import com.sto.stoapp.thread.ServerSmsThread;
import com.sto.stoapp.thread.TimeSynchThread;
import com.sto.stoapp.util.Helper;
import com.sto.stoapp.widget.BaseActivity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import sto.android.app.StoJNI;

/**
 * 下载服务
 * 
 * @author mgf
 * 
 */
@SuppressLint({ "HandlerLeak", "UseSparseArrays", "NewApi" })
public class StoDownServer extends Service implements MessageType {

	/**
	 * 后台下载状态
	 */
	public static final String SERVER_DOWN_STATUS = "server_down_status";

	// 广播action
	public static final String UPDATE_ACTION = "update_action";
	// 广播更新事件
	private static final int UPDATE_BROAD_CAST = 0xfd;
	// 订单下载的量
	private int orderCount;
	// 订单提醒的数量
	private int orderNoticeCount;

	private String siteCodeNumber; // = StoFilePreference.getInstance(
	// StoDownServer.this).getSiteCode();

	private String jobNumber; // = StoFilePreference.getInstance(
	// StoDownServer.this).getUserInfo();

	private UpdateBroad updateBroad;

	public static HashMap<Integer, Integer> updateBuffer;

	private List<String> OrderNotice = new ArrayList<String>();
	BlockingQueue<Runnable> workQueue;
	private final static int POOL_SIZE = 4;// 线程池的大小最好设置成为CUP核数的2N
	private final static int MAX_POOL_SIZE = 6;// 设置线程池的最大线程数
	private final static int KEEP_ALIVE_TIME = 5;// 设置线程的存活时间
	private Executor mExecutor;
	private Handler broadHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (UPDATE_BROAD_CAST == msg.what) {
				int[] downList = (int[]) msg.obj;
				if (downList == null) {
					return;
				}
				for (int entity : downList) {
					if (updateBuffer.containsKey(entity)) {
						Helper.showToast(StoDownServer.this, StoDownServer.this
								.getText(R.string.down_requesting).toString());
					} else {
						synchronized (updateBuffer) {
							updateBuffer.put(entity, entity);
						}
						addPool(entity);
					}
				}
			}
		}

	};

	// 在线程池中执行线程
	public void submit() {
		if (workQueue == null)
			workQueue = new LinkedBlockingDeque<Runnable>();
		if (mExecutor == null) {
			ThreadFactory factory = new PriorityThreadFactory("thread-pool",
					android.os.Process.THREAD_PRIORITY_BACKGROUND);
			mExecutor = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE,
					KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue, factory);
		}
		Runnable r = workQueue.poll();
		if (r != null)
			mExecutor.execute(r);

	}

	private Handler handler = new Handler() {

		@SuppressWarnings({ "rawtypes", "unchecked" })
		@Override
		public void handleMessage(final Message msg) {
			super.handleMessage(msg);
			// Log.d("stodownServer", "handleMessage");
			if (mExecutor == null) {
				updateBuffer.clear();
				// Log.d("stodownServer", "****handleMessage*****");
				return;
			}
			switch (msg.what) {
			case SERVER_SMS_TYPE:
				if (msg == null || msg.obj == null) {
					Helper.showToast(StoDownServer.this, StoDownServer.this
							.getText(R.string.server_sms_down_fail).toString());
					break;
				}

				String data = msg.obj.toString();

				if (data != null) {
					int result = ServerSmsManager.getInstance(
							StoDownServer.this).insertList(data);
					if (result == 0) {
						// Helper.showToast(StoDownServer.this, "服务点短信0条");
					} else {

						// Helper.showToast(StoDownServer.this,
						// StoDownServer.this
						// .getText(R.string.server_sms_down_success)
						// .toString());
					}
				} else {
					Helper.showToast(StoDownServer.this, StoDownServer.this
							.getText(R.string.server_sms_down_fail).toString());
				}
				updateBuffer.remove(SERVER_SMS_TYPE);
				break;

			case BILLCODE_ISSUE:
				if (!msg.obj.toString().equals("")
						&& msg.obj.toString() != null) {
					Helper.showToast(StoDownServer.this, msg.obj.toString());
				} else {
					Helper.showToast(StoDownServer.this,
							getText(R.string.billcode_issue_down_fail)
									.toString());
				}

				break;
			// 时间同步
			case SYNCH_TIME_TYPE:
				TimeSynchResponse response = (TimeSynchResponse) msg.obj;
				if (response != null && response.getLongTime() != null) {
					StoJNI jni = StoApplication.getStoJni();
					jni.SetSystemTime(response.getLongTime());
					StoFilePreference.getInstance(StoDownServer.this)
							.setPowerOffTime(
									Long.parseLong(response.getLongTime()));
					StoFilePreference.getInstance(StoDownServer.this)
							.setTimeSynch(true);
					new DeleteDataThread(StoDownServer.this).start();
					Helper.showLongToast(StoDownServer.this,
							getText(R.string.synch_time_success).toString());
				} else {
					Log.i("sto", "时间同步失败");
					StoFilePreference.getInstance(StoDownServer.this)
							.setTimeSynch(false);
					showTimeErrorDialog("时间同步失败");

				}
				break;
			default:
				break;

			}

			updateBuffer.remove(msg.what);
		}

	};

	public static void removeDownType(int type) {
		updateBuffer.remove(type);
	}

	/**
	 * 订单刷新
	 * 
	 * @author wxf
	 */
	private void sendOrderRefresh() {

		Intent intent = new Intent(BaseActivity.REFRESH_ORDER_ACTION);

		sendBroadcast(intent);
	}

	private void addToQueu(Runnable runable) {
		workQueue.add(runable);
		submit();
	}

	AlertDialog tdialog = null;

	private void showTimeErrorDialog(String str) {

		LayoutInflater flater = LayoutInflater.from(this);
		View view = flater.inflate(R.layout.sto_sales_order_notice, null);
		Builder builder = new AlertDialog.Builder(this);

		TextView msgCancelText = (TextView) view
				.findViewById(R.id.order_notice_detailview);
		msgCancelText.setTextColor(Color.WHITE);
		msgCancelText.setText(str);

		builder.setTitle("提示")
				.setView(view)
				.setPositiveButton(R.string.confirm,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.dismiss();
								tdialog = null;
							}
						});

		tdialog = builder.create();
		tdialog.getWindow().setType(
				(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
		tdialog.setCancelable(true);
		tdialog.setOnCancelListener(new OnCancelListener() {

			@Override
			public void onCancel(DialogInterface dialog) {
				tdialog = null;
			}
		});
		tdialog.show();

	}

	private AlertDialog _dialog = null;

	private void showOrderInfo(String message) {
		if (!message.equals("")) {
			if (_dialog == null) {
				// System.out.println("message:" + message);
				String cancelMsg = "";

				String hastenMsg = "";

				Helper.vibratorToast(this, 500);
				LayoutInflater flater = LayoutInflater.from(this);
				View view = flater.inflate(R.layout.sto_sales_order_notice,
						null);
				Builder builder = new AlertDialog.Builder(this);

				TextView msgCancelText = (TextView) view
						.findViewById(R.id.order_notice_cancelview);

				TextView msgHastenText = (TextView) view
						.findViewById(R.id.order_notice_detailview);

				String stmsg[] = message.split("<FF01>");

				if (stmsg.length > 0) {
					for (String noticest : stmsg) {
						String clmsg[] = noticest.split("<FF00>");
						if (clmsg.length > 1) {
							for (String noticecl : clmsg) {
								cancelMsg += noticecl;
							}
						} else {
							hastenMsg += noticest;
						}
					}

				} else {
					stmsg = message.split("<FF00>");
					if (stmsg.length > 0) {
						for (String noticecel : stmsg) {
							String msgst[] = noticecel.split("<FF01>");
							if (msgst.length > 1) {
								for (String stnotice : msgst) {
									hastenMsg += stnotice;
								}
							} else {
								cancelMsg += noticecel;
							}
						}

					}
				}
				if (hastenMsg.equals("")) {
					msgHastenText.setVisibility(view.GONE);
				} else {
					msgHastenText.setText(hastenMsg);
				}
				if (!cancelMsg.equals("")) {
					msgCancelText.setVisibility(view.VISIBLE);
					msgCancelText.setText(cancelMsg);
				}

				builder.setTitle("提示")
						.setView(view)
						.setPositiveButton(R.string.confirm,
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										dialog.dismiss();
										_dialog = null;
									}
								});

				_dialog = builder.create();
				_dialog.getWindow().setType(
						(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
				_dialog.setCancelable(true);
				_dialog.setOnCancelListener(new OnCancelListener() {

					@Override
					public void onCancel(DialogInterface dialog) {
						_dialog = null;
					}
				});
				_dialog.show();
				new OrderNoticeTempFile().deleteContents();
				// SoundManager.getInstance(this).playFailureSound();
				Helper.showSoundAndVibrator(this, false);
			}

		}
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();

		siteCodeNumber = StoFilePreference.getInstance(this).getSiteCode();

		jobNumber = StoFilePreference.getInstance(this).getUserCode();

		updateBuffer = new HashMap<Integer, Integer>();
		updateBroad = new UpdateBroad();
		registerReceiver(updateBroad, new IntentFilter(UPDATE_ACTION));
		ThreadFactory factory = new PriorityThreadFactory("thread-pool",
				android.os.Process.THREAD_PRIORITY_BACKGROUND);
		// 创建工作队列
		workQueue = new LinkedBlockingDeque<Runnable>();
		mExecutor = new ThreadPoolExecutor(POOL_SIZE, MAX_POOL_SIZE,
				KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue, factory);

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		if (intent == null) {
			return super.onStartCommand(intent, flags, startId);
		}
		int[] downList = intent.getIntArrayExtra(SERVER_DOWN_STATUS);
		if (downList == null) {
			return super.onStartCommand(intent, flags, startId);
		}
		for (int entity : downList) {
			synchronized (updateBuffer) {
				if (!updateBuffer.containsKey(entity)) {
					updateBuffer.put(entity, entity);
				}
			}
			addPool(entity);

		}
		return super.onStartCommand(intent, flags, startId);
	}

	private void doOtherData(int type) {

		EnunDownLoad downLoadType = null;

		switch (type) {

		// 问题件下载ISSUE_TABLE
		case PROBLEM_TYPE:
			downLoadType = EnunDownLoad.ISSUE_TABLE;
			break;
		// USER_TABLE
		// case OFFLINE_LOGIN:
		// downLoadType = EnunDownLoad.USER_TABLE;
		// break;
		// REGION_TABLE
		case PROVINCE_TYPE:
			downLoadType = EnunDownLoad.REGION_TABLE;
			break;
		// ORDER_RETURN_REASON_TABLE
		case ORDER_REASON_TYPE:
			downLoadType = EnunDownLoad.ORDER_RETURN_REASON_TABLE;
			break;
		// ORG_TABLE
		case SITE_CODE_FULL:
			downLoadType = EnunDownLoad.ORG_TABLE;
			break;
		// NEXT_STOP_TABLE
		case NEXT_SITE_CODE:
			downLoadType = EnunDownLoad.NEXT_STOP_TABLE;
			break;
		// EMP_TABLE
		case SITE_SALEAS_TYPE:
			downLoadType = EnunDownLoad.EMP_TABLE;
			break;
		// 路由下载ROUTE_TABLE
		case AVIATION_ROUTE:
			downLoadType = EnunDownLoad.ROUTE_TABLE;
			break;

		// USER_INFO_TABLE 用户基本信息
		case USER_INFO_TABLE:
			downLoadType = EnunDownLoad.USER_INFO_TABLE;
			break;
		case OFFLINE_LOGIN:
			downLoadType = EnunDownLoad.USER_TABLE;
			break;
		case SYSTEM_TABLE:
			downLoadType = EnunDownLoad.SYSTEM_TABLE;
			break;
		case ORG_RULE_TABLE:
			downLoadType = EnunDownLoad.ORG_RULE_TABLE;
			break;
		case USER_RULE_TABLE:
			downLoadType = EnunDownLoad.USER_RULE_TABLE;
			break;
		case DATADICT_TABLE:
			downLoadType = EnunDownLoad.DATADICT_TABLE;
			break;
		case GOODS_TYPE_TABLE:
			downLoadType = EnunDownLoad.GOODS_TYPE_TABLE;
			break;
		case EFFECTIVE_TYPE_TABLE:
			downLoadType = EnunDownLoad.EFFECTIVE_TYPE_TABLE;
			break;
		case FREQUENCY_TABLE:
			downLoadType = EnunDownLoad.FREQUENCY_TABLE;
			break;
		case SCAN_RULE_TABLE:
			downLoadType = EnunDownLoad.SCAN_RULE_TABLE;
			break;

		default:
			ExceptionLog.writeLog(type + "");
			return;
		}
		addToQueu(new BasicDataDLThread(this, handler, downLoadType, type));
	}

	private void addPool(int messageType) {

		if (mExecutor == null) {
			updateBuffer.clear();
			return;
		}

		// 服务短信下载(保留)
		if (messageType == SERVER_SMS_TYPE) {
			ServerSmsRequest smsRequest = new ServerSmsRequest();
			smsRequest.setData(StoFilePreference.getInstance(this)
					.getSiteCode());
			addToQueu(new ServerSmsThread(this, smsRequest, handler));
		}
		// 面单发放(保留)
		else if (messageType == BILLCODE_ISSUE
				&& StoFilePreference.getInstance(this).getReceiveControl()) {
			addToQueu(new CodeIssueThread(this, BILLCODE_ISSUE, handler));
		} else if (messageType == SYNCH_TIME_TYPE) {
			addToQueu(new TimeSynchThread(this, handler, false));
		} else if (messageType == ORDER_DOWNLOAD_TYPE) {
			// 订单下载

			addToQueu(new OrderDownThread(this, handler, messageType));
		} else {
			// 其他表下载方式
			doOtherData(messageType);
		}

	}

	public static int getTaskSize() {
		if (updateBuffer == null) {
			return -1;
		}
		synchronized (updateBuffer) {
			return updateBuffer.size();
		}

	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		handler.removeMessages(PROBLEM_TYPE);
		handler.removeMessages(OFFLINE_LOGIN);
		handler.removeMessages(PROVINCE_TYPE);
		handler.removeMessages(ORDER_REASON_TYPE);
		handler.removeMessages(SITE_CODE_FULL);
		handler.removeMessages(NEXT_SITE_CODE);
		handler.removeMessages(SITE_SALEAS_TYPE);
		handler.removeMessages(SERVER_SMS_TYPE);
		handler.removeMessages(AVIATION_ROUTE);

		if (updateBroad != null) {
			unregisterReceiver(updateBroad);
		}
	}

	class UpdateBroad extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (action.equals(UPDATE_ACTION)) {
				if (!Helper.isNetworkAvailable(context)) {
					Helper.showToast(context, "网络不可用，下载失败，请检查网络。");
					return;
				}
				Message msg = broadHandler.obtainMessage();
				msg.what = UPDATE_BROAD_CAST;
				msg.obj = intent.getIntArrayExtra(SERVER_DOWN_STATUS);
				broadHandler.sendMessage(msg);
			}
		}
	}
}
